package com.carey.blog.action.file;

import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONObject;

import com.carey.blog.framework.latke.Keys;
import com.carey.blog.model.File;
import com.carey.blog.model.Preference;
import com.carey.blog.util.Preferences;
import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;

/**
 * File access via <a
 * href="http://code.google.com/appengine/docs/java/blobstore/"> Google Blog
 * Store</a>.
 * 
 */
public final class BlobStoreFileAccessServlet extends HttpServlet {

	/**
	 * Logger.
	 */
	private static final Logger LOGGER = Logger
			.getLogger(BlobStoreFileAccessServlet.class.getName());
	/**
	 * Default serial version uid.
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * File repository.
	 */
	// @Inject
	// private FileRepository fileRepository;
	/**
	 * Datastore service.
	 */
	private DatastoreService datastoreService = DatastoreServiceFactory
			.getDatastoreService();
	/**
	 * Blog info factory.
	 */
	private BlobInfoFactory blobInfoFactory = new BlobInfoFactory(
			datastoreService);
	/**
	 * Blob service.
	 */
	private BlobstoreService blobstoreService = BlobstoreServiceFactory
			.getBlobstoreService();
	/**
	 * Preference utilities.
	 */
	private Preferences preferenceUtils = Preferences.getInstance();

	@Override
	protected void doPost(final HttpServletRequest request,
			final HttpServletResponse response) throws ServletException,
			IOException {
		LOGGER.info("Uploading file....");
		final Map<String, BlobKey> blobs = blobstoreService
				.getUploadedBlobs(request);
		final BlobKey blobKey = blobs.get("myFile");

		if (null == blobKey) {
			LOGGER.log(Level.SEVERE, "File upload error");
			response.sendRedirect("/");
		} else {
			try {
				final BlobInfo blobInfo = blobInfoFactory.loadBlobInfo(blobKey);
				final String blobId = blobKey.getKeyString();
				final JSONObject file = new JSONObject();
				file.put(Keys.OBJECT_ID, blobId);
				file.put(File.FILE_DOWNLOAD_COUNT, 0);

				final String contentType = blobInfo.getContentType();
				final Date createDate = blobInfo.getCreation();
				file.put(File.FILE_UPLOAD_DATE, createDate);
				final String fileName = blobInfo.getFilename();
				file.put(File.FILE_NAME, fileName);
				final long fileSize = blobInfo.getSize();
				file.put(File.FILE_SIZE, fileSize);
				final JSONObject preference = preferenceUtils.getPreference();
				if (null == preference) {
					response.sendError(HttpServletResponse.SC_NOT_FOUND);
					return;
				}

				final String host = "http://"
						+ preference.getString(Preference.BLOG_HOST);
				final String downloadURL = host + "/file-access.do?oId="
						+ blobId;
				file.put(File.FILE_DOWNLOAD_URL, downloadURL);

				// fileRepository.add(file);
				LOGGER.log(Level.INFO, "Uploaded file[name={0}, size={1}]",
						new Object[] { fileName, fileSize });
				response.sendRedirect(downloadURL);
			} catch (final Exception e) {
				LOGGER.log(Level.SEVERE, "File upload error");
				response.sendRedirect("/");
			}
		}
	}

	@Override
	protected void doGet(final HttpServletRequest request,
			final HttpServletResponse response) throws ServletException,
			IOException {
		LOGGER.finer("Getting a file....");
		final BlobKey blobKey = new BlobKey(
				request.getParameter(Keys.OBJECT_ID));
		final String blobId = blobKey.getKeyString();
		// try {
		// final JSONObject file = fileRepository.get(blobId);
		// final int cnt = file.getInt(File.FILE_DOWNLOAD_COUNT);
		// file.put(File.FILE_DOWNLOAD_COUNT, cnt + 1);
		// fileRepository.update(blobId, file);
		// } catch (final Exception e) {
		// LOGGER.warning("Inc file download count error!");
		// }

		blobstoreService.serve(blobKey, response);
	}
}
